package com.fp.m7.client.view;

import gwtupload.client.IUploader;
import gwtupload.client.IUploader.OnFinishUploaderHandler;
import gwtupload.client.SingleUploaderModal;

import com.fp.m7.client.MyMessages;
import com.fp.m7.client.presenter.SettingsPresenter;
import com.fp.m7.client.widget.ConfirmDialogBox;
import com.fp.m7.client.widget.ExtendedTextBox;
import com.fp.m7.client.widget.InfoPopup;
import com.fp.m7.shared.Constants;
import com.fp.m7.shared.ValidationConstants;
import com.fp.m7.shared.ValidationError;
import com.fp.m7.shared.ValidationResult;
import com.fp.m7.shared.dto.AccountDto;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratedStackPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Has a stack panel handling four activities:<br>
 * uploading an avatar picture, changing status and description<br>
 * changing nickname<br>
 * changing password<br>
 * deleting the account.
 * 
 * @author 7
 */
public class SettingsView extends Composite implements SettingsPresenter.Display {

    private static MyMessages msg = GWT.create(MyMessages.class);

    private Image imgPhoto;
    private TextBox tbStatus;
    private TextArea taDescription;
    private Button btnSaveChanges;
    private Label lblCurrentNicknamePreview;
    private TextBox tbNewNickname;
    private Button btnChangeNickname;
    private PasswordTextBox tbOldPassword;
    private PasswordTextBox tbNewPassword;
    private PasswordTextBox tbNewPasswordRpt;
    private Button btnChangePassword;
    private Button btnDeleteAccount;
    private SingleUploaderModal uploader;

    private ConfirmDialogBox confirmAccountDeletionDialogBox;

    public SettingsView() {
        DecoratedStackPanel decoratedStackPanel = new DecoratedStackPanel();
        initWidget(decoratedStackPanel);
        decoratedStackPanel.addStyleName("fillBothDirections");

        VerticalPanel basicPanel = new VerticalPanel();
        basicPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        decoratedStackPanel.add(basicPanel, msg.basic(), false);
        basicPanel.setSize("100%", "100%");

        AbsolutePanel basicAbsolutePanel = new AbsolutePanel();
        basicPanel.add(basicAbsolutePanel);
        basicAbsolutePanel.setSize("473px", "286px");

        Label lblPhoto = new Label(msg.photo());
        basicAbsolutePanel.add(lblPhoto, 10, 10);
        lblPhoto.setSize("100px", "24px");

        imgPhoto = new Image(Constants.DEFAULT_AVATAR_URL);
        basicAbsolutePanel.add(imgPhoto, 116, 10);
        imgPhoto.setSize("100px", "100px");

        uploader = new SingleUploaderModal();
        basicAbsolutePanel.add(uploader, 222, 10);
        uploader.setSize("240px", "24px");

        Label lblStatus = new Label(msg.status());
        basicAbsolutePanel.add(lblStatus, 10, 120);
        lblStatus.setSize("100px", "24px");

        tbStatus = new TextBox();
        basicAbsolutePanel.add(tbStatus, 116, 116);
        tbStatus.setSize("338px", "16px");
        tbStatus.setMaxLength(160);

        Label lblDescription = new Label(msg.description());
        basicAbsolutePanel.add(lblDescription, 10, 150);
        lblDescription.setSize("100px", "24px");

        taDescription = new TextArea();
        basicAbsolutePanel.add(taDescription, 116, 150);
        taDescription.setSize("340px", "90px");
        taDescription.addStyleName("notResizable");

        btnSaveChanges = new Button(msg.saveChanges());
        basicAbsolutePanel.add(btnSaveChanges, 321, 252);
        btnSaveChanges.setSize("140px", "24px");

        VerticalPanel changeNicknamePanel = new VerticalPanel();
        changeNicknamePanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        decoratedStackPanel.add(changeNicknamePanel, msg.changeNickname(), false);
        changeNicknamePanel.setSize("100%", "100%");

        AbsolutePanel chNickAbsolutePanel = new AbsolutePanel();
        changeNicknamePanel.add(chNickAbsolutePanel);
        chNickAbsolutePanel.setSize("442px", "100px");

        Label lblCurrentNickname = new Label(msg.currentNickname());
        chNickAbsolutePanel.add(lblCurrentNickname, 10, 10);
        lblCurrentNickname.setSize("140px", "24px");

        lblCurrentNicknamePreview = new Label("");
        chNickAbsolutePanel.add(lblCurrentNicknamePreview, 156, 10);
        lblCurrentNicknamePreview.setSize("280px", "24px");

        Label lblNewNickname = new Label(msg.newNickname());
        chNickAbsolutePanel.add(lblNewNickname, 10, 40);
        lblNewNickname.setSize("140px", "24px");

        tbNewNickname = new ExtendedTextBox();
        chNickAbsolutePanel.add(tbNewNickname, 156, 40);
        tbNewNickname.setSize("268px", "12px");

        btnChangeNickname = new Button(msg.changeNickname());
        chNickAbsolutePanel.add(btnChangeNickname, 272, 66);
        btnChangeNickname.setSize("160px", "24px");
        btnChangeNickname.setEnabled(false);

        VerticalPanel changePasswordPanel = new VerticalPanel();
        changePasswordPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        decoratedStackPanel.add(changePasswordPanel, msg.changePassword(), false);
        changePasswordPanel.setSize("100%", "100%");

        AbsolutePanel chPwdAbsolutePanel = new AbsolutePanel();
        changePasswordPanel.add(chPwdAbsolutePanel);
        chPwdAbsolutePanel.setSize("315px", "150px");

        Label lblOldPassword = new Label(msg.currentPassword());
        lblOldPassword.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
        chPwdAbsolutePanel.add(lblOldPassword, 10, 14);
        lblOldPassword.setSize("140px", "24px");

        tbOldPassword = new PasswordTextBox();
        chPwdAbsolutePanel.add(tbOldPassword, 150, 10);

        Label lblNewPassword = new Label(msg.newPassword());
        lblNewPassword.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
        chPwdAbsolutePanel.add(lblNewPassword, 10, 48);
        lblNewPassword.setSize("140px", "24px");

        tbNewPassword = new PasswordTextBox();
        chPwdAbsolutePanel.add(tbNewPassword, 150, 44);

        Label lblRepeatNewPasswrd = new Label(msg.repeatNewPassword());
        lblRepeatNewPasswrd.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
        chPwdAbsolutePanel.add(lblRepeatNewPasswrd, 10, 88);
        lblRepeatNewPasswrd.setSize("140px", "24px");

        tbNewPasswordRpt = new PasswordTextBox();
        chPwdAbsolutePanel.add(tbNewPasswordRpt, 150, 78);

        btnChangePassword = new Button(msg.changePassword());
        chPwdAbsolutePanel.add(btnChangePassword, 150, 112);
        btnChangePassword.setSize("155px", "24px");

        VerticalPanel advancedPanel = new VerticalPanel();
        advancedPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        decoratedStackPanel.add(advancedPanel, msg.advanced(), false);
        advancedPanel.setSize("100%", "100%");

        AbsolutePanel advancedAbsolutePanel = new AbsolutePanel();
        advancedPanel.add(advancedAbsolutePanel);
        advancedAbsolutePanel.setSize("125px", "47px");

        confirmAccountDeletionDialogBox = new ConfirmDialogBox();
        confirmAccountDeletionDialogBox.setHTML(msg.deleteAccountDisclaimer());

        btnDeleteAccount = new Button(msg.deleteAccount());
        advancedAbsolutePanel.add(btnDeleteAccount, 10, 10);
        btnDeleteAccount.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent paramClickEvent) {
                confirmAccountDeletionDialogBox.showCentered();
            }
        });
    }

    @Override
    public void configureUploader(String uploadUrl, String[] validAvatarExtensions) {
        uploader.setServletPath(uploadUrl);
        uploader.setValidExtensions(validAvatarExtensions);
    }

    @Override
    public void setContent(AccountDto accountDto) {
        if (accountDto != null) {
            tbStatus.setText(accountDto.getStatus());
            taDescription.setText(accountDto.getDescription());

            String avatarUrl = accountDto.getUserDto().getAvatarUrl();
            imgPhoto.setUrl(avatarUrl == null ? Constants.DEFAULT_AVATAR_URL : avatarUrl);
            lblCurrentNicknamePreview.setText(accountDto.getUserDto().getNickname());

            tbNewNickname.setText("");
            clearPasswords();
        }
    }

    @Override
    public HasValueChangeHandlers<String> getNewNicknameInput() {
        return tbNewNickname;
    }

    @Override
    public HasClickHandlers getChangeNicknameButton() {
        return btnChangeNickname;
    }

    @Override
    public HasClickHandlers getUpdateStatusAndDescriptionButton() {
        return btnSaveChanges;
    }

    @Override
    public HasClickHandlers getDeleteAccountButton() {
        return confirmAccountDeletionDialogBox.getConfirmButton();
    }

    @Override
    public HasText getNickname() {
        return tbNewNickname;
    }

    @Override
    public HasText getStatus() {
        return tbStatus;
    }

    @Override
    public HasText getDescription() {
        return taDescription;
    }

    @Override
    public void setNicknameAvailable(Boolean value) {
        btnChangeNickname.setEnabled(value == null ? false : value.booleanValue());

        if (value == null) {
            btnChangeNickname.setText(msg.checkingAvailability());
        } else {
            btnChangeNickname.setText(value ? msg.changeNickname() : msg.nicknameNotAvailable());
        }
    }

    @Override
    public void setUploadFinishedEvent(final Command event) {
        uploader.addOnFinishUploadHandler(new OnFinishUploaderHandler() {
            @Override
            public void onFinish(IUploader uploader) {
                imgPhoto.setUrl(uploader.fileUrl());
                event.execute();
            }
        });
    }

    @Override
    public HasText getOldPassword() {
        return tbOldPassword;
    }

    @Override
    public HasText getNewPassword() {
        return tbNewPassword;
    }

    @Override
    public HasText getNewPasswordRepeated() {
        return tbNewPasswordRpt;
    }

    @Override
    public HasClickHandlers getChangePasswordButton() {
        return btnChangePassword;
    }

    @Override
    public void clearPasswords() {
        tbOldPassword.setText("");
        tbNewPassword.setText("");
        tbNewPasswordRpt.setText("");
    }

    @Override
    public void showErrors(ValidationResult result) {
        for (ValidationError error : result) {
            if (ValidationConstants.Fields.NEW_PASSWORD.equals(error.getFieldName())) {
                InfoPopup.showPopup(tbNewPassword, msg.newPasswordRegexFail());
            } else if (ValidationConstants.Fields.NEW_PASSWORD_REPEATED.equals(error.getFieldName())) {
                InfoPopup.showPopup(tbNewPasswordRpt, msg.passwordsDoNotMatch());
            } else if (ValidationConstants.Fields.PASSWORD.equals(error.getFieldName())) {
                InfoPopup.showPopup(tbOldPassword, msg.wrongPassword());
            } else if (ValidationConstants.Fields.STATUS.equals(error.getFieldName())) {
                InfoPopup.showPopup(tbStatus, msg.statusRegexFail());
            } else if (ValidationConstants.Fields.DESCRIPTION.equals(error.getFieldName())) {
                InfoPopup.showPopup(taDescription, msg.descriptionRegexFail());
            }
        }
    }

}
